package pers.cz.controller;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Value;
import pers.cz.encrypt.DesUtil;
import pers.cz.kettle.DataSyncUtil;
import pers.cz.model.DatabaseDtl;
import pers.cz.pub.RespBean;
import pers.cz.service.DataSyncSercice;
import entity.DataBaseParamter;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.pentaho.di.core.exception.KettleException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import pers.cz.tools.StringUtils;

import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @program: PostGirl-panent
 * @description: DataSync
 * @author: Cheng Zhi
 * @create: 2021-05-17 17:31
 **/
@RestController
@Api(tags = "数据同步接口")
@RequestMapping("/api/DataSyncController")
public class DataSyncController {

    private Logger logger = LoggerFactory.getLogger(DataSyncController.class);

    @Autowired
    DataSyncSercice service;

    @PostMapping("/syncData")
    public void syncData(@RequestBody Map map) throws KettleException, IOException {

        String tableNameA = (String) map.get("tableNameSource");
        String tableNameB = (String) map.get("tableNameTarget");

        String strA = JSON.toJSONString(map.get("paramterSource")); //转化成JSON字符串
        DataBaseParamter paramterA  = JSON.parseObject(strA,DataBaseParamter.class); //将JSON转化成对象
        String strB = JSON.toJSONString(map.get("paramterTarget")); //转化成JSON字符串
        DataBaseParamter paramterB  = JSON.parseObject(strB,DataBaseParamter.class); //将JSON转化成对象
        if (paramterA.getType().equalsIgnoreCase("antdb")) {
            paramterA.setType("PostgreSQL");
        }
        if (paramterB.getType().equalsIgnoreCase("antdb")) {
            paramterB.setType("PostgreSQL");
        }
        String sql = (String) map.get("sql");
        if (sql == null || sql.length() <= 0) {
            sql = "select * from " + paramterA.getDataBaseName() + "." + tableNameA;
        }
        String primaryKeys = (String) map.get("primaryKey");
        String updatelookups = (String) map.get("updatelookup");
        String[] primaryKey = primaryKeys.split(",");
        String[] updatelookup = null;
        if (updatelookups != null && updatelookups.length() > 0) {
            updatelookup = StringUtils.split(updatelookups, ",");
        }
        paramterA.setPassword(DesUtil.decode(paramterA.getPassword())); // 解密
        paramterB.setPassword(DesUtil.decode(paramterB.getPassword())); // 解密
        DataSyncUtil.executeTransForm(paramterA, paramterB, tableNameA, tableNameB, sql, primaryKey, updatelookup);
        //DataSyncUtil.getKtr(paramterA, paramterB, tableNameA, tableNameB, sql, primaryKey, updatelookup);
    }

    @PostMapping("/saveKettle")
    public void saveKettle(@RequestBody Map map) throws KettleException, IOException {

        String tableNameA = (String) map.get("tableNameSource");
        String tableNameB = (String) map.get("tableNameTarget");

        String strA = JSON.toJSONString(map.get("paramterSource")); //转化成JSON字符串
        DataBaseParamter paramterA  = JSON.parseObject(strA,DataBaseParamter.class); //将JSON转化成对象
        String strB = JSON.toJSONString(map.get("paramterTarget")); //转化成JSON字符串
        DataBaseParamter paramterB  = JSON.parseObject(strB,DataBaseParamter.class); //将JSON转化成对象

        if (paramterA.getType().equalsIgnoreCase("antdb")) {
            paramterA.setType("PostgreSQL");
        }
        if (paramterB.getType().equalsIgnoreCase("antdb")) {
            paramterB.setType("PostgreSQL");
        }

        paramterA.setPassword(DesUtil.decode(paramterA.getPassword()));
        paramterB.setPassword(DesUtil.decode(paramterB.getPassword()));
        String sql = (String) map.get("sql");

        String primaryKeys = (String) map.get("primaryKey");
        String updatelookups = (String) map.get("updatelookup");
        String[] primaryKey = primaryKeys.split(",");
        String[] updatelookup = updatelookups.split(",");

        //DataSyncUtil.executeTransForm(paramterA, paramterB, tableNameA, tableNameB, sql, primaryKey, updatelookup);
        DataSyncUtil.getKtr(paramterA, paramterB, tableNameA, tableNameB, sql, primaryKey, updatelookup);
    }

    /**
     * 添加数据库信息
     * @return
     */
    @ApiOperation(value = "添加数据库信息")
    @PostMapping("/addDataBaseDtl")
    public RespBean addDataBaseDtl(@RequestBody Map map) {

        String connectionName = (String) map.get("connectionName");
        String ip = (String) map.get("ip");
        String portString = (String)map.get("port");
        String type = (String) map.get("type");
        String connectionMode = (String) map.get("connectionMode");
        String databaseName  = (String) map.get("databaseName");
        String username = (String) map.get("username");
        String password = (String) map.get("password");
        String passwordEncrypt = DesUtil.encrypt(password); // 密码需要加密保存

        DatabaseDtl dtl = new DatabaseDtl();
        dtl.setConnectionName(connectionName);
        dtl.setIp(ip);
        dtl.setPort(Integer.valueOf(portString));
        dtl.setType(type);
        dtl.setConnectionMode(connectionMode);
        dtl.setDatabaseName(databaseName);
        dtl.setUsername(username);
        dtl.setPassword(passwordEncrypt);
        dtl.setUpdateDate(DateUtil.date());
        dtl.setCreateDate(DateUtil.date());
        int count = service.addDatabaseDtl(dtl);

        return RespBean.ok("成功添加[" + count + "]条");
    }

    /**
     * 查询所有数据库连接名，用于下拉框展示
     * @return
     */
    @ApiOperation(value = "查询所有数据库连接名，用于下拉框展示")
    @GetMapping("/queryALLDataBaseDtl")
    public List<DatabaseDtl> queryALLDataBaseDtl() {

       return service.queryALLDataBaseDtl();
    }

    @ApiOperation(value = "分页查询所有数据库连接")
    @PostMapping("/queryAllDataBaseDtlByPage")
    public List<DatabaseDtl> queryAllDataBaseDtlByPage(@RequestBody Map map) {

        int pageStart = (int) map.get("pageStart");
        int pageLimit = (int) map.get("pageLimit");

        // 处理密码，将密码展示的时候替换为******
        List<DatabaseDtl> databaseDtls = service.queryALLDataBaseDtlByPage(pageStart, pageLimit);

        List<DatabaseDtl> databaseDtlsNew = new ArrayList<>();
        for (DatabaseDtl dtl :  databaseDtls) {

            DatabaseDtl newDtl = new DatabaseDtl();

            newDtl.setUsername(dtl.getUsername());
            newDtl.setDatabaseName(dtl.getDatabaseName());
            newDtl.setConnectionMode(dtl.getConnectionMode());
            newDtl.setType(dtl.getType());
            newDtl.setPort(dtl.getPort());
            newDtl.setIp(dtl.getIp());
            newDtl.setPassword("********");
            newDtl.setId(dtl.getId());
            newDtl.setCreateDate(dtl.getCreateDate());
            newDtl.setUpdateDate(dtl.getUpdateDate());
            newDtl.setConnectionName(dtl.getConnectionName());

            databaseDtlsNew.add(newDtl);
        }

        return databaseDtlsNew;
    }

    @ApiOperation(value = "获取数据库连接总数")
    @GetMapping("/getDataBaseDtlTotalNum")
    public Integer getDataBaseDtlTotalNum() {

        return service.getDataBaseDtlTotalNum();
    }

    @ApiOperation(value = "修改数据库连接")
    @PostMapping("/updateDataBaseDtl")
    public RespBean updateDataBaseDtl(@RequestBody Map map) {

        DatabaseDtl databaseDtl = new DatabaseDtl();

        int id = (int) map.get("id");
        String connectionName = (String) map.get("connectionName");
        String ip = (String) map.get("ip");
        int port = (int) map.get("port");
        String type = (String) map.get("type");
        String connectionMode = (String) map.get("connectionMode");
        String databaseName = (String) map.get("databaseName");
        String username = (String) map.get("username");
        String password = (String) map.get("password");
        if (password != null && !password.equals("") && !"********".equals(password)) {
            String passwordEncrypt = DesUtil.encrypt(password); // 密码需要加密保存
            databaseDtl.setPassword(passwordEncrypt);
        }
        databaseDtl.setId(id);
        databaseDtl.setConnectionName(connectionName);
        databaseDtl.setIp(ip);
        databaseDtl.setPort(port);
        databaseDtl.setType(type);
        databaseDtl.setConnectionMode(connectionMode);
        databaseDtl.setDatabaseName(databaseName);
        databaseDtl.setUsername(username);
        databaseDtl.setUpdateDate(DateUtil.date());
        int count = service.updateDataBaseDtl(databaseDtl);
        return RespBean.ok("修改成功[" + count + "]条");
    }

    @ApiOperation(value = "删除数据库连接")
    @PostMapping("/deleteDataBaseDtl")
    public RespBean deleteDataBaseDtl(@RequestBody Map map) {

        int id = (int) map.get("id");
        int count = service.deleteDataBaseDtl(id);

        return RespBean.ok("删除成功[" + count + "]条");
    }

    @ApiOperation(value = "探测数据库可用性")
    @PostMapping("/detectionDb")
    public RespBean detectionDb(@RequestBody Map map) {
        String str = JSON.toJSONString(map.get("paramterSource")); //转化成JSON字符串
        DataBaseParamter paramter  = JSON.parseObject(str,DataBaseParamter.class); //将JSON转化成对象
        if (paramter.getType().equalsIgnoreCase("antdb")) {
            paramter.setType("PostgreSQL");
        }
        paramter.setPassword(DesUtil.decode(paramter.getPassword())); // 解密
        String sql = "select 1";
        if (paramter.getType().equalsIgnoreCase("oracle")) {
            sql = "select 1 from dual";
        }
        try {
            // 探测失败
            List<String> stringList = DataSyncUtil.executeSql(paramter, sql);
            return RespBean.ok("数据库可用;", true);
        } catch (Exception e) {
            logger.error("探测异常", e);
            return RespBean.error("数据库不可用，请检查！", false);
        }

    }
}
